// Package config @Title config[简述该包的主要作用]
// @Description
// @Author  cnHuaShao
// @since v0.0.1
// @Version v1.0.0
// @Date 2024/4/21 22:25
// @Update 2024/4/21 22:25
package config

import (
	"FinancialManagement/conf"
	"FinancialManagement/src/base/env"
	"FinancialManagement/src/base/util"
	"bytes"
	"fmt"
	"github.com/fsnotify/fsnotify"
	"github.com/spf13/viper"
	"log"
	"os"
	"path/filepath"
)

var (
	// SysConfigDir 配置文件所在目录
	SysConfigDir = "./conf/"
	// SysConfigName 配置文件名称
	SysConfigName = "dev_configs"
	// SysConfigType 配置文件类型
	SysConfigType = "toml"
	// SysConfigFilePath 配置文件完整地址
	SysConfigFilePath = ""
	// dataList 数据集合
	dataList map[string]string
)

type ConfigData struct {
	Code string `json:"Code"`
	Msg  string `json:"Msg:"`
	Data struct {
		Elements []struct {
			Id         string `json:"Id"`
			Name       string `json:"Name"`
			Value      string `json:"value"`
			AsdCode    string `json:"asd_code"`
			UpdateTime string `json:"update_time"`
			Note       string `json:"note"`
		} `json:"elements"`
	} `json:"Data"`
}

// 获取当前执行程序所在的绝对路径
func getCurrentAbPathByExecutable() string {
	exePath, err := os.Executable()
	if err != nil {
		log.Fatal(err)
	}
	res, _ := filepath.EvalSymlinks(filepath.Dir(exePath))
	return res
}

// InitConfig
// @Description: 启动时可以使用d参数进行指定配置文件所在目录
// @return error
// @author zhangyc
func InitConfig() error {
	log.Println("----------------初始配置文件")
	log.Println("getCurrentAbPathByExecutable = ", getCurrentAbPathByExecutable())
	// 加载启动配置
	configLoad()
	return nil
}

// configLoad 配置文件加载内部函数
func configLoad() {

	switch env.Active().Value() {
	case "dev":
		bytes.NewReader(conf.DevConfigs)
	case "fat":
		bytes.NewReader(conf.FatConfigs)
	case "uat":
		bytes.NewReader(conf.UatConfigs)
	case "pro":
		bytes.NewReader(conf.ProConfigs)
	default:
		bytes.NewReader(conf.FatConfigs)
	}
	log.Println(env.Active().Value())
	// 初始化配置文件名称
	SysConfigName = env.Active().Value() + "_configs"
	// 初始化 配置文件完整地址
	SysConfigFilePath = SysConfigDir + SysConfigName + "." + SysConfigType
	// 设定读取名称
	viper.SetConfigName(SysConfigName)
	// 设定配置文件类型
	viper.SetConfigType(SysConfigType)
	// 设定扫描目录
	viper.AddConfigPath(SysConfigDir)
	// 读取配置文件
	if err := viper.ReadInConfig(); err != nil {
		panic(err)
	}
	if err := viper.Unmarshal(config); err != nil {
		panic(err)
	}
	// 判断配置文件是否存在，如果不存在则进行创建该文件。用于初始启动时自动创建好配置文件，后续就可以修改该文件了
	_, ok := util.IsExists(SysConfigFilePath)
	if !ok {
		if err := os.MkdirAll(filepath.Dir(SysConfigFilePath), 0766); err != nil {
			panic(err)
		}

		f, err := os.Create(SysConfigFilePath)
		if err != nil {
			panic(err)
		}
		defer f.Close()

		if err := viper.WriteConfig(); err != nil {

			panic(err)
		}
	}
	// 配置文件被修改时再次读取
	viper.WatchConfig()
	// 观察配置文件是否被变更
	viper.OnConfigChange(func(e fsnotify.Event) {
		if err := viper.Unmarshal(config); err != nil {
			panic(err)
		}
		fmt.Println("Config file changed:", e.Name)
	})
}
